//~ `New testbench
`timescale  1ns / 1ps  

module tb_aes_top;     

// aes_top Parameters  
parameter PERIOD  = 10;

// aes_top Inputs
reg   clk                                  = 1 ;
reg   rst_n                                = 0 ;
reg   load                                 = 0 ;
reg   [4:0]  CMD                           = 0 ;
reg   [127:0]  intxt                       = 0 ;

// aes_top Outputs
wire  keyexprdy                            ;
wire  encdecrdy                            ;
wire  [127:0]  outtxt                      ;

initial
begin
    forever #(PERIOD/2)  clk=~clk;
end

initial
begin
    #(PERIOD*2) rst_n  =  1;
end
reg test_ok=0;
aes_top  u_aes_top (
    .clk                     ( clk                ),
    .rst_n                   ( rst_n              ),
    .load                    ( load               ),
    .CMD                     ( CMD        [4:0]   ),
    .intxt                   ( intxt      [127:0] ),

    .keyexprdy               ( keyexprdy          ),
    .encdecrdy               ( encdecrdy          ),
    .outtxt                  ( outtxt     [127:0] )
);
integer fd_intxt,fd_key,fd_outtxt,fd_test_intxt,fd_test_outtxt;
reg [127:0]t;
// initial
// begin
//     #(PERIOD*2 + 7);

//     fd_intxt       = $fopen("./test_data/intxt.info"      ,"r");
//     fd_key         = $fopen("./test_data/key.info"        ,"r");
//     fd_outtxt      = $fopen("./test_data/outtxt.info"     ,"r");
//     fd_test_intxt  = $fopen("./test_data/intxt_test.info" ,"w");
//     fd_test_outtxt = $fopen("./test_data/outtxt_test.info","w");

//     while (!$feof(fd_intxt)) begin
//         // 载入初始密钥
//         $fscanf(fd_key,"%h",t);
//         task_exp_key(t);

//         // 明文 加密
//         $fscanf(fd_intxt,"%h",t);
//         task_encode(t);
//         $fwrite(fd_test_outtxt,"%h\n",outtxt);

//         // 密文 解密
//         $fscanf(fd_outtxt,"%h",t);
//         task_decode(t);
//         $fwrite(fd_test_intxt,"%h\n",outtxt);
//         rst_n = 0;
//         #(PERIOD);
//         rst_n = 1;
//         #(PERIOD*100-3);
//     end
    
//     test_ok = 1;
//     $stop;
// end

// initial
// begin
//     #(PERIOD*2 + 7);

//     fd_intxt       = $fopen("./test_data/5.jpg"      ,"r");
//     fd_key         = $fopen("./test_data/key.info"        ,"r");
//     fd_outtxt      = $fopen("./test_data/outtxt.info"     ,"r");
//     fd_test_intxt  = $fopen("./test_data/intxt_test.info" ,"w");
//     fd_test_outtxt = $fopen("./test_data/outtxt_test.info","w");
    
//     // 载入初始密钥
//     $fscanf(fd_key,"%h",t);
//     task_exp_key(t);

//     while (!$feof(fd_intxt)) begin
//         // 明文 加密
//         $fscanf(fd_intxt,"%h",t);
//         task_decode(t);
//         $fwrite(fd_test_outtxt,"%h\n",outtxt);

//         // 密文 解密
//         // $fscanf(fd_outtxt,"%h",t);
//         // task_decode(t);
//         // $fwrite(fd_test_intxt,"%h\n",outtxt);
//         // rst_n = 0;
//         // #(PERIOD);
//         // rst_n = 1;
//         #(PERIOD*10-3);
//     end
    
//     test_ok = 1;
//     $stop;
// end


initial
begin
    #(PERIOD*2);

    // 载入初始密钥
    task_exp_key(128'h20019A755023EE22404B7858366BFD5C);
   
    // 明文
    task_encode(128'h123E491A325FF63B9E3A7D79495FDC0D);

    // 密文
    task_decode(128'hB01330349B90700C287F9FC8338C4072);

    $stop;
end

task task_exp_key;
    input [127:0]key_r;
    begin
        //载入初始密钥
        load = 1;
        CMD = 5'b10000;
        intxt = key_r;

        // 开始扩展密钥
        #(PERIOD);
        load = 1;
        CMD = 5'b01000;

        #(PERIOD)
        load = 0;

        @(posedge keyexprdy); // 等待密钥加载完毕
    end
endtask

// 加密任务
task task_encode;
    input [127:0]intxt_r;
    begin
        #(8);
        // 载入明文
        load = 1;
        CMD = 5'b10000;
        intxt = intxt_r;

        #(PERIOD);
        load = 1;
        CMD = 5'b00100;

        #(PERIOD);
        load = 0;

        @(posedge encdecrdy);
        #(PERIOD);
    end
endtask

task task_decode;
    input [127:0]intxt_r;
    begin
        #(8);
        // 载入明文
        load = 1;
        CMD = 5'b10000;
        intxt = intxt_r;

        #(PERIOD);
        load = 1;
        CMD = 5'b00010;

        #(PERIOD);
        load = 0;

        @(posedge encdecrdy);
        #(PERIOD);
    end
endtask

// 文件操作
endmodule